package com.ruoyi.web.core.config;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author : zhurenwang
 * @date : 2022/1/19
 * @description :如果有多个切面order注解声明执行顺序;可添加异步线程写入日志到ES
 */
@Aspect
@Order(1)
@Component
public class WebControllerAop {

    private static final Logger log = LoggerFactory.getLogger(WebControllerAop.class);

    ThreadLocal<Long> startTime = new ThreadLocal<>();

    @Pointcut("normalPointcutWeb()")
    public void log() {
    }

    @Pointcut("execution(public * com.ruoyi.web.xxj.contoller.*.*(..))")
    public void normalPointcutWeb() {
    }


    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        startTime.set(System.currentTimeMillis());
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.info("===========================================");
        log.info("request url ->{}", request.getRequestURL().toString());
        log.info("request method ->{}", request.getMethod());
        log.info("request ip ->{}", request.getRemoteAddr());
        log.info("Class Method ->{}", joinPoint.getSignature().getDeclaringTypeName() + "#" + joinPoint.getSignature().getName());
        try {
            log.info("request params ->{} ", JSONObject.toJSONString(joinPoint.getArgs(), JSONWriter.Feature.PrettyFormat));
        } catch (Exception e) {
            log.error("e", e);
        }

    }

    @AfterReturning(returning = "ret", pointcut = "log()")
    public void doAfterReturning(Object ret) {
        log.info("response json ->{} ", JSONObject.toJSONString(ret, JSONWriter.Feature.PrettyFormat));
        log.info("cost time ->{}ms", System.currentTimeMillis() - startTime.get());
        startTime.remove();
    }
}
